namespace RBAC.Read.Api.Application.Handler.ERP.OutboundManagement
{
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Threading;
    using MediatR;
    using Microsoft.Extensions.Logging;
    using RBAC.Domain.Dto.Output;
    using RBAC.Domain.MaterialManage;
    using RBAC.Domain.OutboundManage;
    using RBAC.ErrorCode;
    using RBAC.Interstructrue.Base;
    using RBAC.Read.Api.Application.Command.ERP.OutboundManagement;
    using RBAC.Read.Api.Application.Dto.ERP;

    /// <summary>
    /// 根据ID获取销售出库详情 处理器
    /// </summary>
    public class GetSalesOutboundByIdHandler : IRequestHandler<GetSalesOutboundByIdCommand, APIResult<SalesOutboundDetailDto>>
    {
        private readonly IBaseRepository<SalesOutbound> outboundRepo;
        private readonly IBaseRepository<SalesOutboundDetail> detailRepo;
        private readonly IBaseRepository<Mater> materRepo;
        private readonly ILogger<GetSalesOutboundByIdHandler> logger;

        public GetSalesOutboundByIdHandler(
            IBaseRepository<SalesOutbound> outboundRepo,
            IBaseRepository<SalesOutboundDetail> detailRepo,
            IBaseRepository<Mater> materRepo,
            ILogger<GetSalesOutboundByIdHandler> logger)
        {
            this.outboundRepo = outboundRepo;
            this.detailRepo = detailRepo;
            this.materRepo = materRepo;
            this.logger = logger;
        }

        public Task<APIResult<SalesOutboundDetailDto>> Handle(GetSalesOutboundByIdCommand request, CancellationToken cancellationToken)
        {
            var result = new APIResult<SalesOutboundDetailDto>();
            try
            {
                logger.LogInformation("开始获取销售出库详情 Id={Id}", request.Id);

                // 获取主表
                var header = outboundRepo.GetFirstOrDefault("Id = @Id", new { Id = request.Id });
                if (header == null)
                {
                    result.Code = APIEnums.Fail;
                    result.Msg = "未找到对应的销售出库单";
                    result.Data = null;
                    return Task.FromResult(result);
                }

                // 获取明细
                var details = detailRepo.GetAll("SalesOutboundId = @SalesOutboundId", new { SalesOutboundId = header.Id });

                // 物料信息
                var materIds = details.Select(d => d.MaterId).Distinct().ToList();
                var materMap = new Dictionary<long, Mater>();
                if (materIds.Any())
                {
                    // 参考销售订单实现：组装 IN 子句参数，避免部分环境下列表参数不被扩展
                    var inClause = string.Join(",", materIds.Select((_, index) => $"@Id{index}"));
                    var parameters = materIds.Select((id, index) => new { Key = $"@Id{index}", Value = id })
                        .ToDictionary(x => x.Key, x => (object)x.Value);

                    var maters = materRepo.GetAll($"Id IN ({inClause})", parameters);
                    materMap = maters.ToDictionary(m => m.Id, m => m);
                }

                var dto = new SalesOutboundDetailDto
                {
                    Id = header.Id,
                    OrderCode = header.OrderCode,
                    OrderDate = header.OrderDate,
                    CustomerCode = header.CustomerCode,
                    CustomerName = header.CustomerName,
                    OrderStatus = header.OrderStatus,
                    BusinessStatus = header.BusinessStatus,
                    Warehouse = header.Warehouse,
                    DeliveryNo = header.DeliveryNo,
                    DeliveryType = header.DeliveryType,
                    Remark = header.Remark,
                    Items = details.Select(d =>
                    {
                        materMap.TryGetValue(d.MaterId, out var m);
                        return new SalesOutboundDetailItemDto
                        {
                            Id = d.Id,
                            MaterId = d.MaterId,
                            MaterCode = m?.MaterCode,
                            MaterName = m?.MaterName,
                            Unit = m?.Unit,
                            ModelSpec = m?.ModelSpec,
                            CopyTradCode = d.CopyTradCode,
                            Num = d.Num,
                            Remark = d.Remark
                        };
                    }).ToList()
                };

                result.Code = APIEnums.Success;
                result.Msg = "获取销售出库详情成功";
                result.Data = dto;
            }
            catch (Exception ex)
            {
                logger.LogError(ex, "获取销售出库详情失败: {Message}", ex.Message);
                result.Code = APIEnums.Error;
                result.Msg = "获取销售出库详情失败";
                result.Data = null;
            }

            return Task.FromResult(result);
        }
    }
}
